package com.chenyun.satoken.starter.util;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpLogic;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 自定义的上下文
 * <p>
 * <font color="red">除本项目外,不要显示调用此类,请使用SaUtil</font>
 *
 * @author: lonni
 * @CreateTime: 2023-09-28  21:27
 * @Description:
 */
public class SatokenContext {
    /**
     * loginType和StpLogic对应缓存
     */
    private static final Map<String, StpLogic> STP_LOGIC_MAP = new ConcurrentHashMap<>();

    private static final Map<String, SaSession> SA_SESSION_MAP = new ConcurrentHashMap<>();

    /**
     * 存储当前请求的loginType类型
     */
    private static final ThreadLocal<String> REQUEST_TOKEN_LOGIN_TYPE = new InheritableThreadLocal<>();

    private SatokenContext() {
    }

    public static SatokenContext instance = new SatokenContext();


    public void setStpLogic(String loginType, StpLogic logic) {
        STP_LOGIC_MAP.putIfAbsent(loginType, logic);
    }

    public StpLogic getStpLogic(String loginType) {
        StpLogic stpLogic = STP_LOGIC_MAP.get(loginType);
        if (stpLogic == null) {
            stpLogic = SaManager.getStpLogic(loginType);
            this.setStpLogic(loginType, stpLogic);
        }
        return stpLogic;
    }

    public StpLogic getStpLogic() {
        StpLogic stpLogic = getStpLogic(REQUEST_TOKEN_LOGIN_TYPE.get());
        return stpLogic;
    }


    public void setSession(String loginType, SaSession session) {
        SA_SESSION_MAP.putIfAbsent(loginType, session);
    }

    public SaSession getSession(String loginType) {
        SaSession session = SA_SESSION_MAP.get(loginType);
        if (session == null) {
            session = getStpLogic().getTokenSession(false);
            this.setSession(loginType, session);
        }
        return session;
    }

    public SaSession getSession() {
        SaSession session = getSession(REQUEST_TOKEN_LOGIN_TYPE.get());
        return session;
    }


    public static void putLoginType(String type) {
        REQUEST_TOKEN_LOGIN_TYPE.set(type);
    }

    public static void removeLoginType() {
        REQUEST_TOKEN_LOGIN_TYPE.remove();
    }

    public static String getLoginType() {
        return REQUEST_TOKEN_LOGIN_TYPE.get();
    }


}
